<template>
  <el-select
    ref="selectRef"
    v-model="selectedValue"
    class="tree-select"
    :clearable="true"
    :disabled="disabled"
    :placeholder="placeholder"
    @change="handleChange"
    @clear="handleClear"
    @visible-change="handleVisibleChange"
  >
    <el-option :label="selectedLabel" style="height: auto; padding: 0" :value="selectedValue">
      <el-tree
        ref="treeRef"
        v-loading="loading"
        :data="treeData"
        default-expand-all
        highlight-current
        node-key="id"
        :props="defaultProps"
        :show-checkbox="false"
        @node-click="handleNodeClick"
      />
    </el-option>
  </el-select>
</template>

<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import Public from '~/src/api/public'

const props = defineProps({
  modelValue: {
    type: [String, Number],
    default: '',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  placeholder: {
    type: String,
    default: '请选择',
  },
  api: {
    type: String,
    default: '/api/department',
  },
  params: {
    type: Object,
    default: () => ({}),
  },
  props: {
    type: Object,
    default: () => ({
      children: 'children',
      label: 'name',
    }),
  },
})

const emit = defineEmits(['update:modelValue', 'change'])

const selectRef = ref()
const treeRef = ref()
const treeData = ref<any[]>([])
const selectedValue = ref<string | number>('')
const selectedLabel = ref<string>('')
const loading = ref(false)

// 树的配置
const defaultProps = computed(() => ({
  children: 'children',
  label: 'name',
  ...props.props,
}))

// 根据 id 查找节点
const findNodeById = (id: string | number, nodes: any[]): any => {
  for (const node of nodes) {
    if (node.id === id) {
      return node
    }
    if (node.children) {
      const found = findNodeById(id, node.children)
      if (found) return found
    }
  }
  return null
}

// 监听外部值变化
watch(
  () => props.modelValue,
  (newVal) => {
    selectedValue.value = newVal
    if (newVal && treeData.value.length > 0) {
      const node = findNodeById(newVal, treeData.value)
      if (node) {
        selectedLabel.value = node.name
      }
    } else {
      selectedLabel.value = ''
    }
  },
  { immediate: true }
)

// 处理节点点击
const handleNodeClick = (data: any) => {
  selectedValue.value = data.id
  selectedLabel.value = data.name
  emit('update:modelValue', data.id)
  emit('change', data)
  // 手动关闭下拉框
  const select = selectRef.value
  if (select) {
    select.blur()
  }
}

// 处理清除
const handleClear = () => {
  selectedValue.value = ''
  selectedLabel.value = ''
  emit('update:modelValue', '')
  emit('change', null)
}

// 处理值变化
const handleChange = (value: string | number) => {
  if (!value) {
    handleClear()
  }
}

// 获取树数据
const fetchTreeData = async () => {
  if (treeData.value.length > 0) return
  loading.value = true
  try {
    const response = await Public.getDetailApi({
      url: props.api,
      params: props.params,
    })
    const { code, result } = response as unknown as { code: number; result: any[] }
    if (code === 0) {
      treeData.value = result
      // 如果已经有选中值，更新显示标签
      if (selectedValue.value) {
        const node = findNodeById(selectedValue.value, result)
        if (node) {
          selectedLabel.value = node.name
        }
      }
    }
  } catch (error) {
    console.error('获取树数据失败:', error)
  } finally {
    loading.value = false
  }
}

// 处理下拉框显示/隐藏
const handleVisibleChange = (visible: boolean) => {
  if (visible) {
    fetchTreeData()
  }
}

defineExpose({
  treeRef,
  treeData,
  fetchTreeData,
})
</script>

<script lang="ts">
export default {
  name: 'TreeSelect',
}
</script>
<style>
.hidden-popper {
  display: none !important;
}

.tree-select {
  width: 100%;
}

:deep(.el-select-dropdown__item) {
  padding: 0;
  height: auto;
  overflow: hidden;
}

:deep(.el-tree) {
  padding: 8px;
}

:deep(.el-tree-node__content) {
  height: 32px;
}

:deep(.el-select-dropdown__item.selected) {
  font-weight: normal;
}
</style>
